using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;

namespace OpenWaves.ImageTransformations.Web.Controls
{
    public class ResponsiveImageSettings
    {
        public bool RenderXhtmlCompilantMarkup = false;
    }

    [ParseChildren(true, "Breakpoints")]
    public class ResponsiveImage : ImageBase
    {
        public static readonly ResponsiveImageSettings Settings = new ResponsiveImageSettings();

        private readonly ImageBreakpointCollection breakpoints = new ImageBreakpointCollection();

        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public ImageBreakpointCollection Breakpoints
        {
            get { return this.breakpoints; }
        }

        protected ImageBreakpoint DefaultBreakpoint
        {
            get { return this.Breakpoints.FirstOrDefault(); }
        }

        private bool? renderXhtmlCompilantMarkup;
        public bool RenderXhtmlCompilantMarkup
        {
            get { return this.renderXhtmlCompilantMarkup ?? Settings.RenderXhtmlCompilantMarkup; }
            set { this.renderXhtmlCompilantMarkup = value; }
        }

        protected override void OnPreRender(System.EventArgs e)
        {
            if (this.RenderXhtmlCompilantMarkup)
            {
                var b = GetResponsiveImageBreakpoints(this, this.ResolveUrl(this.ImageUrl), this.Breakpoints, this.Transformation,
                                                         this.CustomTransformation);
                var script = new StringBuilder();
                foreach (var br in b)
                {
                    script.AppendFormat("$('#{0}').data('{1}', '{2}');", this.ClientID, br.Key, br.Value);
                }
                this.Page.ClientScript.RegisterStartupScript(typeof(ResponsiveImage), this.UniqueID, script.ToString(), true);
            }
        }

        protected override void RenderImage(string imageUrl, HtmlTextWriter writer)
        {
            if (string.IsNullOrEmpty(imageUrl))
            {
                this.RenderImageTag("", writer, false);
                return;
            }

            imageUrl = this.ResolveUrl(imageUrl);

            IDictionary<string, string> data = null;
            if (RenderXhtmlCompilantMarkup == false)
            {
                data = GetResponsiveImageBreakpoints(this, imageUrl, this.Breakpoints, this.Transformation,
                                                     this.CustomTransformation);
            }

            this.RenderImageTag("#", writer, this.RenderXhtmlCompilantMarkup, "display: none", data);

            if (this.DefaultBreakpoint != null)
            {
                writer.RenderBeginTag(HtmlTextWriterTag.Noscript);
                this.RenderImageTag(
                    imageUrl,
                    this.DefaultBreakpoint.Transformation ?? this.Transformation,
                    this.CustomTransformation,
                    this.DefaultBreakpoint.Width,
                    this.DefaultBreakpoint.Height,
                    writer);
                writer.RenderEndTag();
            }
        }

        public static IDictionary<string, string> GetResponsiveImageBreakpoints(Control control, string imageUrl, IEnumerable<ImageBreakpoint> breakpoints, ImageTransformationType defaultTransformation, string defaultCustomTransformation)
        {
            var imageTransformationService = ServiceLocator.Resolve<IWebImageTransformationService>();
            
            return breakpoints.ToDictionary(
                b => b.Name.ToLowerInvariant()+"-src",
                b =>
                {
                    var transformation = b.Transformation != null ?
                        b.Transformation.Value.CreateImageTransformation(b.CustomTransformation, b.Width, b.Height) : 
                        defaultTransformation.CreateImageTransformation(defaultCustomTransformation, b.Width, b.Height);

                    var transformedImageUrl = imageTransformationService.GetTransformedImageUrl(Url.Parse(string.IsNullOrEmpty(b.ImageUrl) ? imageUrl : control.ResolveUrl(b.ImageUrl)), transformation);

                    return control.ResolveUrl(transformedImageUrl.ToString());
                });
        }

        public static object GetResponsiveImageOptions(Control control, string imageUrl, IEnumerable<ImageBreakpoint> breakpoints, ImageTransformationType defaultTransformation, string defaultCustomTransformation)
        {
            var options = new
                {
                    id = control.ClientID,
                    breakpoints = GetResponsiveImageBreakpoints(control, imageUrl, breakpoints, defaultTransformation, defaultCustomTransformation)
                };

            return options;
        }
    }
}